--[[
human复活相关逻辑
--]]


local Lang = require("common.Lang")
local ExcelMapConf = require("excel.Map")
local Msg = require("core.Msg")
local Map = require("core.Map")
local Obj = require("core.Obj")
local ObjHuman = require("core.ObjHuman")
local RoleFFI = require("role.RoleFFI")
local Timer = require("core.Timer")
local ItemDefine = require("bag.ItemDefine")
local Copy = require("copy.CopyL")
local BagLogic = require("bag.BagLogic")
local Aim = require("copy.Aim")
local ObjPet = require("core.ObjPet")
local JZWar = require("copy.JZWar")
local FamilyWar = require("copy.FamilyWar")
local DHFight = require("copy.DHFight")
local CCJJWar = require("copy.CCJJWar")
local CopyHandlerL = require("copy.HandlerL")
local MonthCardLogic = require("vip.MonthCardLogic")
local CopyDefine = require("copy.Define")

local function set_hp(human, hp, pre)
    --print(_G.debug.traceback())
    local maxx = ObjHuman.getHpMax(human)
    local nSetHp = 0
    if hp < maxx then
        nSetHp = math.floor(hp)
    else
        nSetHp = maxx
    end

    if pre and pre ~= 0 then
        human.db.hp = math.floor(nSetHp * (pre / 100))
    else
        human.db.hp = nSetHp 
    end
    --	ObjPet.callPet(human)
    --	local tomb = ObjTomb.create()
    --	Obj.enterScene(tomb, human.scene_id, human.x, human.y)

    --	ActivityCallback.onHumanReviveCB(human)
end

function getReviveLeftTime(human)
    local copyID = Copy.isCopyBySceneID(human.scene_id)
    local map_id = Map.scene_id_to_map_id[human.scene_id]
    if not ExcelMapConf.scene[map_id] then
        return 0, 0
    end
    local cf = ExcelMapConf.scene[map_id].revive
    if cf[1] == 1 then
        local t = cf[2] - (os.time() - human.db.dieTime)
        if t < 0 then
            t = 0
        end
        return t, cf[3]
    elseif cf[1] == 2 then
        local t = cf[2] - (os.time() - human.db.dieTime)
        if t < 0 then
            t = 0
        end
        return t, cf[3]
    elseif cf[1] == 6 then
        return 0, cf[6] 
    end

    if copyID then
        if cf[1] == 3 then              --普通副本
            local nDieTimeSplit = os.time() - human.db.dieTime
            local nAddDieTime = 0
            if human.db.copyDieCount >= 2 then
                if nDieTimeSplit < cf[4] then
                    nAddDieTime = (human.db.copyDieCount - 1) * (cf[5] or 0)
                end
            end
            local nTempTime = cf[2] + nAddDieTime
            return (nTempTime > cf[6] and cf[6] or nTempTime) - (os.time() - human.db.dieTime), cf[3]
        elseif cf[1] == 4 then          --回城副本
            return 0, cf[2] - (os.time() - human.db.dieTime)
        elseif cf[1] == 5 then          --荆州争夺战
            if copyID == CopyDefine.COPY_JZWAR_ID then
                return JZWar.onGetReviveTime(human._id), 0
            elseif copyID == CopyDefine.COPY_FAMILYWAR_ID then
                return FamilyWar.onGetReviveTime(human._id), 0
            elseif copyID == CopyDefine.COPY_DHFIGHT_ID1 
                or copyID == CopyDefine.COPY_DHFIGHT_ID2
                or copyID == CopyDefine.COPY_DHFIGHT_ID3
                or copyID == CopyDefine.COPY_DHFIGHT_ID4
                or copyID == CopyDefine.COPY_DHFIGHT_ID5 then
                return DHFight.onGetReviveTime(human._id), 0
            elseif copyID == CopyDefine.COPY_CCJJWAR_ID then
                return CCJJWar.onGetReviveTime(human._id), 0
            end
        end
    end
    return 0, 0
end

function getReviveItemCnt(human, itemID)
    local map_id = Map.scene_id_to_map_id[human.scene_id]
    local cfReviveItem = ExcelMapConf.scene[map_id].reviveItem
    for k, v in ipairs(cfReviveItem) do
        if v[1] == itemID then
            if v[3] and v[3] == 1 then
                if MonthCardLogic.isHaveSpec(human) then
                    return 0
                end
            end
            local cf = ExcelMapConf.scene[map_id].revive
            --local nTimeSplit = 60000 
            if cf[1] == 6 then
                local tempCnt = human.db.reviveNowItemNum
                tempCnt = tempCnt + 1 
                if tempCnt > (cf[2] or 0) then 
                    tempCnt = (cf[2] or 0)
                end
                return tempCnt
            else
                --if Timer.now - human.db.reviveNowTime < nTimeSplit then
                    local tempCnt = human.db.reviveNowItemNum
                    tempCnt = tempCnt + 1 
                    if tempCnt > 5 then tempCnt = 5 end
                    return tempCnt
                --end
            end
            return v[2]
        end
    end
    return 1
end

function sendHumanDie(human, attacker, onlyOne)
    if human.db.hp > 0 then
        return
    end
    local mm = Msg.gc.GC_HUMAN_DIE
    mm.obj_id = human.id
    if attacker then
        attacker = attacker.owner and Obj.getOwner(attacker) or attacker
    end
    mm.attackerType = human.db.killerType or 0
    mm.attacker =  RoleFFI.ffi_string(human.db.killerName)
    if not mm.attacker or mm.attacker == "" or mm.attacker == "aoe_name" then
        mm.attacker = "场景机关"
    end
    mm.revive_time, mm.autorevive_time = getReviveLeftTime(human)

    local map_id = Map.scene_id_to_map_id[human.scene_id]
    local cf = ExcelMapConf.scene[map_id].revive
    local revive_type = cf[1]
    mm.revive_type = revive_type
    mm.die_txt = ExcelMapConf.scene[map_id].die_txt

    local nItemData = ExcelMapConf.scene[map_id].reviveItem --复活消耗的道具
    mm.revive_item[0] = 0
    for k, v in ipairs(nItemData) do
        mm.revive_item[0] = mm.revive_item[0] + 1
        local nReviveItemMsg = mm.revive_item[mm.revive_item[0]]
        local itemName = ItemDefine.getValue(v[1], "name")
        nReviveItemMsg.item_name = itemName
        nReviveItemMsg.item_cnt = getReviveItemCnt(human, v[1]) 
        human.db.reviveNowItemNum = nReviveItemMsg.item_cnt 
    end

    --[[
    if mm.revive_type == 1 then
    mm.item_name = ItemDefine.getValue(cf[2], "name")
    mm.item_cnt = getReviveYuandiItemCnt(human)-- 正常模式下 原地复活需要的药物数量随着一段时间内的次数而增加
    --]]
    if onlyOne then
        Msg.send(mm, human.fd)
    else
        Obj.sendArea(mm, human.scene_id, human.x, human.y)
    end
    --[[
    if ExcelMapConf.scene[map_id].scene_count == 1 and attacker and attacker.obj_type == Obj.TYPE_HUMAN then
    if Copy.isCopy(map_id) == nil then
    local mm = Msg.gc.GC_BROADCAST
    mm.type = Lang.UP+Lang.GROSSIP
    mm.msg = string.format(Lang.REVIVE_ERR_A, HtmlUtil.fontNameKuo(attacker.db.name, attacker.db._id), HtmlUtil.fontNameKuo(human.db.name, human.db._id))
    Obj.sendScene(mm, human.scene_id)
    FriendLogic.addEnemy(human, attacker)
    end
    end
    --]]
end

function send_gc_revive_err(human, err)
    if not err then
        assert()
    end
    local mm = Msg.gc.GC_REVIVE_ERR
    mm.err = err
    Msg.send(mm, human.fd)
end

-- 立刻复活
function reviveNow(human)
    if 0 < human.db.hp then
        return send_gc_revive_err(human, Lang.REVIVE_ERR_STILL_ALIVE)
    end

    local map_id = Map.scene_id_to_map_id[human.scene_id]
    local cf = ExcelMapConf.scene[map_id].revive

    local revive_type = cf[1]
    -- 荆州争夺战爬塔不能原地复活
    if revive_type == 4 or revive_type == 5 or revive_type == 0 then
        return
    end

    local nItemData = ExcelMapConf.scene[map_id].reviveItem --复活消耗的道具
    for k, v in ipairs(nItemData) do
        local itemName = ItemDefine.getValue(v[1], "name")
        --if not MonthCardLogic.isHaveSpec(human) then
        if BagLogic.getItemCount(human, v[1]) < (human.db.reviveNowItemNum or 0) then
            return send_gc_revive_err(human, string.format(Lang.REVIVE_ERR_ITEM, itemName))
        end

        --end
    end

    for k, v in ipairs(nItemData) do
        --if not MonthCardLogic.isHaveSpec(human) then
        local nNeedItemNum = human.db.reviveNowItemNum or 0
        if nNeedItemNum > 0 then
            BagLogic.delItemsById(human, v[1], nNeedItemNum, "item_relive")
            local itemName = ItemDefine.getValue(v[1], "name")
            --needAddBuf = true
            send_gc_revive_err(human, string.format(Lang.REVIVE_TIP_REVIVE_NOW, nNeedItemNum, itemName))
            --end
        end
    end

    human.db.reviveNowTime = Timer.now -- 普通模式下原地复活时间

    set_hp(human, 0x7fffffff, ExcelMapConf.scene[map_id].reviveNowHpPre)
    ObjHuman.doCalc(human)
    local mm = Msg.gc.GC_REVIVE
    mm.obj_id = human.id
    mm.hp = human.db.hp
    mm.type = 1
    Obj.sendArea(mm, human.scene_id, human.x, human.y)
    ObjPet.callPet(human)
end
-- 回城复活

function goHome(human)
    local mapID = Map.HOME_MAP_ID1    --newhome
    local x, y = Map.getHomePoint(mapID)
    ObjHuman.enterMap(human, mapID, x, y)
end


-- type
--type:1 场景复活
function reviveGoHome(human, innerLogic)
    if 0 < human.db.hp then
        return send_gc_revive_err(human, Lang.REVIVE_ERR_STILL_ALIVE)
    end

    local map_id = Map.scene_id_to_map_id[human.scene_id]
    local cf = ExcelMapConf.scene[map_id]

    local nReviveLeftTime = getReviveLeftTime(human)
    if nReviveLeftTime > 0 then
        return send_gc_revive_err(human, Lang.REVIVE_ERR_TIME)
    end

    local revive_type = cf.revive[1]

    -- 荆州争夺战不能安全复活
    if revive_type == 5 and not innerLogic then
        return
    end

    set_hp(human, 0x7fffffff, cf.reviveGoHomeHpPre)
    human.db.reviveNowItemNum = 0
    ObjPet.callPet(human)
    ObjHuman.doCalc(human)

    local mm = Msg.gc.GC_REVIVE
    mm.obj_id = human.id
    mm.hp = human.db.hp
    mm.type = 2
    Obj.sendArea(mm, human.scene_id, human.x, human.y)

    send_gc_revive_err(human, Lang.REVIVE_TIP_REVIVE_GO_HOME)
    local copyID = Copy.isCopy(map_id)
    local roomID = Copy.copyHuman2Room[human._id]
    if copyID and roomID then
        --爬塔复活逻辑
        if revive_type == 4 then
            CopyHandlerL.CG_COPY_LEAVE(human)
        elseif revive_type == 5 then
            if copyID == CopyDefine.COPY_JZWAR_ID then
                JZWar.onJumpBackPos(human, true)
            elseif copyID == CopyDefine.COPY_FAMILYWAR_ID then
                FamilyWar.onJumpBackPos(human, true)
            elseif copyID == CopyDefine.COPY_DHFIGHT_ID1 
                or copyID == CopyDefine.COPY_DHFIGHT_ID2
                or copyID == CopyDefine.COPY_DHFIGHT_ID3
                or copyID == CopyDefine.COPY_DHFIGHT_ID4
                or copyID == CopyDefine.COPY_DHFIGHT_ID5 then
                DHFight.onJumpBackPos(human, true)
            elseif copyID == CopyDefine.COPY_CCJJWAR_ID then
                return CCJJWar.onJumpBackPos(human, true) 
            end
        else
            doCopyReviveHomePos(human, copyID, roomID)
        end
    elseif cf.revive[1] == 6 then
        ObjHuman.enterMap(human, cf.revive[3], cf.revive[4], cf.revive[5])
    else
        local nMapType = Map.getMapTypeBySceneID(human.scene_id)
        if cf.isPVP == 0 then
            Obj.jump(human, cf.x, cf.y, Msg.gc.GC_JUMP)
        else
            goHome(human)
        end
    end
end

function doCopyReviveHomePos(human, copyID, roomID)
    local mapTempID, tempX, tempY = Aim.getEnterMap(copyID, roomID)

    if mapTempID == nil then
        local map_id = Map.scene_id_to_map_id[human.scene_id]
        Obj.jump(human, ExcelMapConf.scene[map_id].x, ExcelMapConf.scene[map_id].y, Msg.gc.GC_JUMP)
        return
    end

    if mapTempID == Map.scene_id_to_map_id[human.scene_id] then
        Obj.jump(human, tempX, tempY, Msg.gc.GC_JUMP)
    else
        ObjHuman.enterMap(human, mapTempID, tempX, tempY)
    end
end
